//
//  UIImage+BizExtension.m
//  MWGX-Customer
//
//  Created by CoolCamel on 17/3/31.
//  Copyright © 2017年 www.meiweigx.com. All rights reserved.
//

#import "UIImage+BizExtension.h"
#import <Accelerate/Accelerate.h>
#import <KSPhotoBrowser/KSPhotoBrowser.h>

@implementation UIImage (BizExtension)
/**
 *  将图片旋转给定的角度
 *
 *  @param degrees 角度
 *
 *  @return 旋转后的图片
 */
- (UIImage*)imageRotatedByDegrees:(CGFloat)degrees{
    CGSize imgSize = CGSizeMake(self.size.width * self.scale, self.size.height * self.scale);
    CGSize outputSize = imgSize;
    //    if (cropMode == enSvCropExpand) {
    //        CGRect rect = CGRectMake(0, 0, imgSize.width, imgSize.height);
    //        rect = CGRectApplyAffineTransform(rect, CGAffineTransformMakeRotation(radian));
    //        outputSize = CGSizeMake(CGRectGetWidth(rect), CGRectGetHeight(rect));
    //    }
    
    UIGraphicsBeginImageContext(outputSize);
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextTranslateCTM(context, outputSize.width / 2, outputSize.height / 2);
    CGContextRotateCTM(context, degrees * M_PI / 180);
    CGContextTranslateCTM(context, -imgSize.width / 2, -imgSize.height / 2);
    
    [self drawInRect:CGRectMake(0, 0, imgSize.width, imgSize.height)];
    
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    
    return image;
}


/**
 *  按（给定高度）比例变化后得到的尺寸
 *
 *  @param height 给定的高度
 *
 *  @return 新的尺寸
 */
-(CGSize) imageGetSizeWithHeight:(CGFloat)height{
    float ratio = self.size.width / self.size.height;
    CGFloat newWidth = ratio * height;
    return CGSizeMake(newWidth, height);
}

/**
 *  按（给定宽度）比例变化后得到的尺寸
 *
 *  @param width 给定的宽度
 *
 *  @return 新的尺寸
 */
-(CGSize) imageGetSizeWithWidth:(CGFloat)width{
    float ratio = self.size.height / self.size.width;
    CGFloat newHeight = ratio * width;
    return CGSizeMake(width, newHeight);
}

-(CGSize) imageFillSizeWithRect:(CGSize)size{
    CGSize widthSize = [self imageGetSizeWithWidth:size.width];
    if (widthSize.height > size.height) {
        CGSize heightSize = [self imageGetSizeWithHeight:size.height];
        return heightSize;
    }
    return widthSize;
}
#pragma mark 图片，颜色相关
/*
 对原来的图片的大小进行处理
 @param image 要处理的图片
 @param size  处理过图片的大小
 */
-(UIImage *)OriginImageScaleToSize:(CGSize)size
{
    UIGraphicsBeginImageContext(size);
    [self drawInRect:CGRectMake(0,0, size.width, size.height)];
    UIImage *scaleImage=UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return scaleImage;
}
//图片放大缩小
-(UIImage *) getImageWithScale:(float) scale{
    
    CGFloat width = self.size.width ;
    CGFloat height = self.size.height;
    
    UIGraphicsBeginImageContext(CGSizeMake(width * scale, height * scale));
    CGContextRef context = UIGraphicsGetCurrentContext();
    //要进行坐标转换
    CGContextTranslateCTM(context, 0, height);
    CGContextScaleCTM(context, 1, -1);
    
    CGContextDrawImage(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, width * scale , height * scale), self.CGImage);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}
//截取图片中某块区域
-(UIImage *) takeSubImagewithRect:(CGRect) rect{
    CGFloat width = rect.size.width;
    CGFloat height = rect.size.height;
    UIGraphicsBeginImageContext(CGSizeMake(width,height));
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextTranslateCTM(context, 0, height);
    CGContextScaleCTM(context, 1, -1);
    CGImageRef newImageRef = CGImageCreateWithImageInRect(self.CGImage, CGRectMake(rect.origin.x, rect.origin.y, width, height));
    CGContextDrawImage(context, CGRectMake(0, 0, width, height) , newImageRef);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    CGImageRelease(newImageRef);
    return newImage;
}

//切取圆形图片
-(UIImage *) takeArcImageWithStart:(CGPoint) start widthRadius:(CGFloat) radius{
    UIGraphicsBeginImageContext(self.size);
    CGContextRef context = UIGraphicsGetCurrentContext();
    
    CGContextMoveToPoint(context, start.x, start.y);
    CGContextAddArc(context, start.x, start.y, radius, 0, M_PI * 2, 1);
    CGContextClosePath(context);
    CGContextClip(context);
    
    CGContextTranslateCTM(context, 0, self.size.height);
    CGContextScaleCTM(context, 1, -1);
    
    CGContextDrawImage(context,CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

-(UIImage *) takeArcImageWithRadius:(CGFloat)radius{
    CGFloat height = self.size.height;
    CGFloat width = self.size.width;
    CGFloat minwidth = MIN(height, width);
    
    CGPoint center = CGPointMake(minwidth / 2, minwidth / 2);
    return [self takeArcImageWithStart:center widthRadius:radius];
}

#pragma mark 图片，颜色相关
//绘制颜色的背景图片
+(UIImage *) imageWithColor:(UIColor *) color size:(CGSize) size{
    UIGraphicsBeginImageContext(size);
    CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), color.CGColor);
    CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width, size.height));
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return image;
}

+ (UIImage *)imageWithText:(NSString *)text textAttr:(NSDictionary *)textAttr {
    
    UIEdgeInsets inset = UIEdgeInsetsMake(1, 2, 1, 2);
    CGFloat cornerRadius = 5;
    CGFloat scale = [[UIScreen mainScreen] scale];
    
    UIFont *font = textAttr[NSFontAttributeName]?textAttr[NSFontAttributeName]:[UIFont systemFontOfSize:10];
    UIColor *bgColor = textAttr[NSBackgroundColorAttributeName]?textAttr[NSBackgroundColorAttributeName]:[UIColor lightGrayColor];
    UIColor *textColor = textAttr[NSForegroundColorAttributeName]?textAttr[NSForegroundColorAttributeName]:[UIColor whiteColor];
    
    NSDictionary *attrDic = @{NSFontAttributeName:font,NSForegroundColorAttributeName:textColor};
    CGSize size = [text sizeWithAttributes:attrDic];
    size.height += inset.top+inset.bottom;
    size.width += inset.right+inset.left;
    
    UIGraphicsBeginImageContext(CGSizeMake(size.width*scale, size.height*scale));
    CGContextAddPath(UIGraphicsGetCurrentContext(), [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, size.width*scale, size.height*scale) cornerRadius:cornerRadius].CGPath);
    CGContextClip(UIGraphicsGetCurrentContext());
    CGContextScaleCTM(UIGraphicsGetCurrentContext(), scale, scale);
    CGContextSetFillColorWithColor(UIGraphicsGetCurrentContext(), bgColor.CGColor);
    CGContextFillRect(UIGraphicsGetCurrentContext(), CGRectMake(0, 0, size.width*scale, size.height*scale));
    [text drawInRect:CGRectMake(inset.right, inset.top, size.width, size.height) withAttributes:attrDic];
    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
    UIImage *i = [UIImage imageWithCGImage:image.CGImage scale:scale orientation:UIImageOrientationUp];
    return i;
}

//为图片着色
-(UIImage *) tintColorWith:(UIColor *)color blendMode:(CGBlendMode)blendMode{
    if (!color) {
        
        return self;
    }
    
    UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
    [color setFill];
    
    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
    UIRectFill(rect);
    
    [self drawInRect:rect blendMode:blendMode alpha:1.0];
    
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return newImage;
}

//返回
+ (UIImage *)gradientColorImageFromColors:(NSArray*)colors gradientType:(GradientType)gradientType imgSize:(CGSize)imgSize{
    NSMutableArray *ar = [NSMutableArray array];

       for(UIColor *c in colors) {

           [ar addObject:(id)c.CGColor];

       }

       UIGraphicsBeginImageContextWithOptions(imgSize, YES, 1);

       CGContextRef context = UIGraphicsGetCurrentContext();

       CGContextSaveGState(context);

       CGColorSpaceRef colorSpace = CGColorGetColorSpace([[colors lastObject] CGColor]);

       CGGradientRef gradient = CGGradientCreateWithColors(colorSpace, (CFArrayRef)ar, NULL);

       CGPoint start;

       CGPoint end;

       switch (gradientType) {

               case GradientTypeTopToBottom:

               start = CGPointMake(0.0, 0.0);

               end = CGPointMake(0.0, imgSize.height);

               break;

               case GradientTypeLeftToRight:

               start = CGPointMake(0.0, 0.0);

               end = CGPointMake(imgSize.width, 0.0);

               break;

               case GradientTypeUpleftToLowright:

               start = CGPointMake(0.0, 0.0);

               end = CGPointMake(imgSize.width, imgSize.height);

               break;

               case GradientTypeUprightToLowleft:

               start = CGPointMake(imgSize.width, 0.0);

               end = CGPointMake(0.0, imgSize.height);

               break;

               default:

               break;

           }

       CGContextDrawLinearGradient(context, gradient, start, end, kCGGradientDrawsBeforeStartLocation | kCGGradientDrawsAfterEndLocation);

       UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

       CGGradientRelease(gradient);

       CGContextRestoreGState(context);

       CGColorSpaceRelease(colorSpace);

       UIGraphicsEndImageContext();

       return image;
}

//返回图片某个像素点的颜色
-(UIColor *) imagePixelColorWithPoint:(CGPoint)point{
    if (!CGRectContainsPoint(CGRectMake(0, 0, self.size.width, self.size.height), point)) {
        
        return nil;
    }
    unsigned char colors[4];
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    
    //只绘制一个像素点
    CGContextRef context = CGBitmapContextCreate(colors, 1, 1, 8, 4, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    
    CGContextTranslateCTM(context, -point.x, point.y - self.size.height);
    CGContextDrawImage(context, CGRectMake(0, 0, self.size.width, self.size.height), self.CGImage);
    
    CGFloat red = (CGFloat)colors[0];
    CGFloat yellow = (CGFloat)colors[1];
    CGFloat green = (CGFloat)colors[2];
    CGFloat alpha = (CGFloat)colors[3];
    
    return [UIColor colorWithRed:red green:yellow blue:green alpha:alpha];
}

//压缩至指定精度
- (NSData *) imageCompressWithDataMaxLength:(NSUInteger)maxLength{
    NSData *data = UIImageJPEGRepresentation(self, 1);
    NSUInteger imageDataLength = data.length;
    if (imageDataLength < maxLength) {
        return data;
    }
    CGFloat ratio = maxLength * 1.0 / imageDataLength;
    return UIImageJPEGRepresentation(self, ratio);
}

- (UIImage *)blurryImageWithBlurLevel:(CGFloat)blur{
    if (blur < 0.f || blur > 1.f) {
        blur = 0.5f;
    }
    int boxSize = (int)(blur * 100);
    boxSize = boxSize - (boxSize % 2) + 1;
    
    CGImageRef img = self.CGImage;
    
    vImage_Buffer inBuffer, outBuffer, outBuffer2;
    vImage_Error error;
    
    void *pixelBuffer;
    
    CGDataProviderRef inProvider = CGImageGetDataProvider(img);
    CFDataRef inBitmapData = CGDataProviderCopyData(inProvider);
    
    inBuffer.width = CGImageGetWidth(img);
    inBuffer.height = CGImageGetHeight(img);
    inBuffer.rowBytes = CGImageGetBytesPerRow(img);
    
    inBuffer.data = (void*)CFDataGetBytePtr(inBitmapData);
    
    pixelBuffer = malloc(CGImageGetBytesPerRow(img) *
                         CGImageGetHeight(img));
    
    if(pixelBuffer == NULL)
        return self;
    
    outBuffer.data = pixelBuffer;
    outBuffer.width = CGImageGetWidth(img);
    outBuffer.height = CGImageGetHeight(img);
    outBuffer.rowBytes = CGImageGetBytesPerRow(img);
    outBuffer2.data = pixelBuffer;
    outBuffer2.width = CGImageGetWidth(img);
    outBuffer2.height = CGImageGetHeight(img);
    outBuffer2.rowBytes = CGImageGetBytesPerRow(img);
    
    error = vImageBoxConvolve_ARGB8888(&inBuffer,&outBuffer2,NULL,0,0,boxSize,boxSize,NULL,kvImageEdgeExtend);
    error = vImageBoxConvolve_ARGB8888(&outBuffer2,&inBuffer,NULL,0,0,boxSize,boxSize,NULL,kvImageEdgeExtend);
    error = vImageBoxConvolve_ARGB8888(&inBuffer,&outBuffer,NULL,0,0,boxSize,boxSize,NULL,kvImageEdgeExtend);
    
    if (error) {
        return self;
    }
    
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGContextRef ctx = CGBitmapContextCreate(
                                             outBuffer.data,
                                             outBuffer.width,
                                             outBuffer.height,
                                             8,
                                             outBuffer.rowBytes,
                                             colorSpace,
                                             kCGImageAlphaNoneSkipLast);
    CGImageRef imageRef = CGBitmapContextCreateImage (ctx);
    UIImage *returnImage = [UIImage imageWithCGImage:imageRef];
    
    //clean up
    CGContextRelease(ctx);
    CGColorSpaceRelease(colorSpace);
    
    free(pixelBuffer);
    CFRelease(inBitmapData);
    
    CGImageRelease(imageRef);
    
    return returnImage;
}

///纠正图片方向
- (UIImage *)fixImageOrientation{
    
    // No-op if the orientation is already correct
    if (self.imageOrientation == UIImageOrientationUp || self == nil)
        return self;
    
    // We need to calculate the proper transformation to make the image upright.
    // We do it in 2 steps: Rotate if Left/Right/Down, and then flip if Mirrored.
    CGAffineTransform transform = CGAffineTransformIdentity;
    
    switch (self.imageOrientation) {
        case UIImageOrientationDown:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, self.size.height);
            transform = CGAffineTransformRotate(transform, M_PI);
            break;
            
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformRotate(transform, M_PI_2);
            break;
            
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, 0, self.size.height);
            transform = CGAffineTransformRotate(transform, -M_PI_2);
            break;
        default:
            break;
    }
    
    switch (self.imageOrientation) {
        case UIImageOrientationUpMirrored:
        case UIImageOrientationDownMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.width, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
            
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRightMirrored:
            transform = CGAffineTransformTranslate(transform, self.size.height, 0);
            transform = CGAffineTransformScale(transform, -1, 1);
            break;
        default:
            break;
    }
    
    // Now we draw the underlying CGImage into a new context, applying the transform
    // calculated above.
    CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height,
                                             CGImageGetBitsPerComponent(self.CGImage), 0,
                                             CGImageGetColorSpace(self.CGImage),
                                             CGImageGetBitmapInfo(self.CGImage));
    CGContextConcatCTM(ctx, transform);
    switch (self.imageOrientation) {
        case UIImageOrientationLeft:
        case UIImageOrientationLeftMirrored:
        case UIImageOrientationRight:
        case UIImageOrientationRightMirrored:
            // Grr...
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage);
            break;
            
        default:
            CGContextDrawImage(ctx, CGRectMake(0,0,self.size.width,self.size.height), self.CGImage);
            break;
    }
    
    // And now we just create a new UIImage from the drawing context
    CGImageRef cgimg = CGBitmapContextCreateImage(ctx);
    UIImage *img = [UIImage imageWithCGImage:cgimg ];//scale:0.5 orientation:UIImageOrientationUp];
    CGContextRelease(ctx);
    CGImageRelease(cgimg);
    
    return img;
}


/// 浏览单张大图
/// @param sourceView 图片的imageView
+ (void)browserImageFromSourceView:(UIImageView *)sourceView {
    [UIImage browserImage:sourceView.image fromSourceView:sourceView];
}

/// 浏览单张大图
/// @param image 图片
/// @param sourceView 来源
+ (void)browserImage:(UIImage *)image
      fromSourceView:(UIView *)sourceView {
    [UIImage browserImage:image fromSourceView:sourceView fromViewController:nil];
}


/// 浏览单张大图
/// @param imageUrl 图片url
/// @param sourceView 来源
+ (void)browserImageUrl:(NSString *)imageUrl
         fromSourceView:(UIView *)sourceView {
    [UIImage browserImageUrl:imageUrl fromSourceView:sourceView fromViewController:nil];
}


/// 浏览单张大图
/// @param image 图片
/// @param sourceView 来源view
/// @param fromController 来源vc
+ (void)browserImage:(UIImage *)image
      fromSourceView:(UIView *)sourceView
  fromViewController:(UIViewController *)fromController {
    NSArray *images = @[];
    
    if (image) {
        images = @[image];
    }
    
    [UIImage browserImages:images fromSourceView:sourceView fromViewController:fromController withIndex:0];
}


/// 浏览单张大图
/// @param imageUrl 图片Url
/// @param sourceView 来源view
/// @param fromController 来源vc
+ (void)browserImageUrl:(NSString *)imageUrl
         fromSourceView:(UIView *)sourceView
     fromViewController:(UIViewController *)fromController {
    NSArray *images = @[];
    if ([imageUrl isNotBlank]) {
        images = @[imageUrl];
    }
    else if ([sourceView isKindOfClass:[UIImageView class]]) {
        UIImage *image = ((UIImageView *)sourceView).image;
        if (image) {
            images = @[image];
        }
    }

    [UIImage browserImages:images fromSourceView:sourceView fromViewController:fromController withIndex:0];
}

/// 浏览大图
/// @param images 图片数组（可以为UIImage或url字符串）
/// @param sourceView 图片的来源UIImageView
/// @param fromController 图片的来源VC
/// @param index 图片为数组中的第几张
+ (void)browserImages:(NSArray *)images fromSourceView:(UIView *)sourceView fromViewController:(UIViewController *)fromController withIndex:(NSInteger)index {
    if (fromController == nil) {
        fromController = [MyAppDelegate getCurrentUIVC];
    }
    NSMutableArray *tempImages = @[].mutableCopy;
    for (id image in images) {
        if ([image isKindOfClass:[NSString class]]) {
            KSPhotoItem *item = [KSPhotoItem itemWithSourceView:sourceView thumbImage:nil imageUrl:[NSURL URLWithString:image]];
            [tempImages addObject:item];
        }
        else if ([image isKindOfClass:[UIImage class]]) {
            KSPhotoItem *item = [KSPhotoItem itemWithSourceView:sourceView thumbImage:image imageUrl:nil];
            [tempImages addObject:item];
        }
    }
    if (index >= tempImages.count) {
        index = (tempImages.count - 1);
    }
    
    if (tempImages.count == 0) {
        return;
    }
    KSPhotoBrowser *browser = [KSPhotoBrowser browserWithPhotoItems:tempImages selectedIndex:index];
    [browser showFromViewController:fromController];
}

@end
